import { Router, json } from "express";
import type { Request, Response } from "express";
import { functionToMcpToolCall } from "../mcp/client";

const router = Router();
router.use(json());
const decoder = new TextDecoder();
router.all("/", async function (req: Request, res: Response) {
    const body = req.body;
    const url = req.query.url as string;
    const method = req.query.method as string;

    if (!url || !method) {
        res.status(400).json({
            error: "Missing required fields: url or method",
        });
        return;
    }
    const urlObj = new URL(url);
    // Convert req.headers to a format compatible with HeadersInit
    const headers = new Headers();
    Object.entries(req.headers).forEach(([key, value]) => {
        if (typeof value === "string") {
            headers.append(key, value);
        } else if (Array.isArray(value)) {
            headers.append(key, value.join(", "));
        }
    });

    try {
        const response = await fetch(url, {
            method,
            headers, // Use the converted headers
            body:
                method !== "GET" && method !== "HEAD"
                    ? JSON.stringify(body)
                    : undefined,
        });

        // Set response headers from the original response
        response.headers.forEach((value, key) => {
            res.setHeader(key, value);
        });

        res.status(response.status);

        if (response.body) {
            // Pipe the readable stream directly to the response
            for await (const chunk of response.body) {
                if (urlObj.pathname === "/api/chat") {
                    await chatFlow(chunk, res);
                } else {
                    res.write(chunk);
                }
            }
            res.end();
        } else {
            const responseBody = await response.text();
            res.send(responseBody);
        }
    } catch (error) {
        console.error("Error while proxying request:", error);
        if (error instanceof Error) {
            res.status(500).json({
                error: "Error while proxying request",
                details: error.message,
            });
        }
    }
});

async function chatFlow(chunk: Uint8Array, res: Response) {
    const jsonStrChunk = decoder.decode(chunk);
    try {
        const data = JSON.parse(jsonStrChunk);
        const message = data.message;
        if (message?.tool_calls) {
            const tool_calls = message.tool_calls;
            const tool_results = await functionToMcpToolCall(tool_calls);
            const newMessage = { ...message, tool_results };
            const newData = { ...data, message: newMessage };
            res.write(JSON.stringify(newData));
        } else {
            res.write(JSON.stringify(data));
        }
    } catch (error) {
        console.error("Error parsing stream chunk:", error);
    }
}

export default router;
